package shiyan3_5;

import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

public class shiyan3_5 {
    public static void main(String[] args)throws Exception{
        KeyPairGenerator aKpairGen = KeyPairGenerator.getInstance("DH") ;
        aKpairGen.initialize(2048);
        KeyPair aKpair = aKpairGen.generateKeyPair();

        KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH");
        aKeyAgree.init(aKpair.getPrivate());

        byte[] aPubKeyEnc = aKpair.getPublic().getEncoded();

        KeyFactory bKeuFac = KeyFactory.getInstance("DH");
        X509EncodedKeySpec x509KeyS = new X509EncodedKeySpec(aPubKeyEnc);
        PublicKey aPubkey = bKeuFac.generatePublic(x509KeyS);

        DHParameterSpec dhParamA_B = ((DHPublicKey)aPubkey).getParams();
        KeyPairGenerator bKpariGen = KeyPairGenerator.getInstance("DH");
        bKpariGen.initialize(dhParamA_B);
        KeyPair bKpar = bKpariGen.generateKeyPair();

        KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH");
        bKeyAgree.init(bKpar.getPrivate());

        byte[] bPubKeyEnc = bKpar.getPublic().getEncoded();

        KeyFactory aKeyFac = KeyFactory.getInstance("DH");
        x509KeyS = new X509EncodedKeySpec(bPubKeyEnc);
        PublicKey bPubkey = aKeyFac.generatePublic(x509KeyS);

        aKeyAgree.doPhase(bPubkey,true);

        byte[] aSharedSecret = aKeyAgree.generateSecret();
        int aliceLen = aSharedSecret.length;
        byte[] bSharedSecret = new byte[aliceLen];

        bKeyAgree.generateSecret(bSharedSecret,0);
        System.out.println(convertByteToHexadecimal(aSharedSecret));
        System.out.println(convertByteToHexadecimal(bSharedSecret));

    }
    public static String convertByteToHexadecimal(byte[] byteArray)
    {
        String hex = "";

        // Iterating through each byte in the array
        for (byte i : byteArray) {
            hex += String.format("%02X", i);
        }

        return hex;
    }

}
